import { List } from "@b/model/base/list";
import { Form } from "@b/model/base/form";
import { ElIcon, ElButton } from "element-plus";
import { ListSearch } from "@b/model/base/list_search";
import { h, type VNode } from "vue";
import { Icon } from "vant";
import 'vant/lib/icon/index.css';
import type { RuleItem } from "async-validator";
import type { interCustomizeTable, listButton } from "@b/model/base/type";
import { pagebuttonStore } from "@b/store";
import { MENUTYPE } from "@b/model/enum";

export class MenuSearch extends ListSearch<interfaceMenu> {
    history: interfaceMenu[] = [{} as interfaceMenu]
    history_length: number = 0
    constructor() {
        super()
        this.data.parentId = 0
        this.reactiveProp = ['isShow', 'parentId', "type"]
    }
    _setLabels() {
        this.setItem({
            parentId: {
                prop: "parentId", label: "上级菜单",
                placeholder: "上级菜单id",
                type: 'text', clearable: true
            },
            name: {
                prop: "name", label: "菜单名",
                type: 'text', clearable: true
            },
            type: {
                prop: "type", label: "类型",
                type: 'select', clearable: true,
                options: [{ value: MENUTYPE.目录, label: '目录' }, { value: MENUTYPE.菜单, label: '菜单' }, { value: MENUTYPE.按钮, label: '按钮' }],
                link: true,
            },
            isShow: {
                prop: "isShow", label: "状态",
                type: 'select', clearable: true,
                options: [{ value: 1, label: '启用' }, { value: 0, label: '禁用' }],
                link: true,
            }
        }, this.labels)
    }
    onLast() {
        const history = this.history
        if (history.length > 1) {
            history.pop()
            const last = history.pop()
            this.setData(last as interfaceMenu)
            this.onSearch()
        }
    }
    init() {
        this._setLabels()
    }
}
export class Menulist extends List<interfaceMenu> {
    constructor() {
        super()
        const type = [...Object.keys(MENUTYPE)]
        this.baseUrl = "/menu"
        this.title = "菜单列表"
        this.select = undefined
        this.immediateCheck = false
        this.labels = {
            id: {
                prop: "id", label: "ID", type: 'customize', width: 80, formatter: ({ value }) => h('div', {
                    className: 'textbutton', onClick: () => this.onSearchWithParent(value)
                }, value)
            },
            name: { prop: "name", label: "菜单名", type: 'text' },
            perms: { prop: "perms", label: "权限", type: 'text', width: 120, overflow: true, default: '无' },
            router: { prop: "router", label: "路径", type: 'text', default: '无' },
            viewPath: { prop: "viewPath", label: "视图地址", type: 'text', default: '无' },
            icon: { prop: "icon", label: "图标", type: 'customize', formatter: () => h(Icon, { name: 'icon' }) },
            img: {
                prop: 'imgUrl', label: '移动端图标', width: 100, type: 'customize', formatter: ({ value }) => value ? h(Icon, { name: value }) : '无'
            },
            parent: { prop: "parent.name", label: "上级菜单", type: 'text' },
            type: { prop: "type", label: "类型", width: 80, type: 'customize', formatter: ({ value }) => type[value] },
            isShow: { prop: "isShow", label: "状态", type: 'switch', onChange: async ({ value, data }) => await this.changeState(value as boolean, data.id) },
            orderNum: { prop: "orderNum", label: "排序", type: 'text', width: 80 }
        }
        this.editButton = () => {
            const but = pagebuttonStore().button
            const buttons: VNode[] = []
            if (but.has('base:menu:add')) {
                buttons.push(h('div', { className: 'textbutton', onClick: this.add }, but.get('base:menu:add')))
                if (this.search_key.parentId) {
                    buttons.push(h('div', { className: 'textbutton', onClick: () => this.onAddChild(this.search_key.parentId) }, '添加子菜单'))
                }
            }
            return buttons
        }
        this.actions = () => {
            const but = pagebuttonStore().button;
            const actions: listButton<interfaceMenu>[] = []
            if (but.has('base:menu:update')) {
                actions.push({
                    text: but.get('base:menu:update') || '',
                    type: 'primary',
                    onClick: (data) => {
                        this.onShowEdit(data.id)
                    }
                })
            }
            if (but.has('base:menu:delete')) {
                actions.push({
                    text: but.get('base:menu:delete') || '',
                    type: 'danger',
                    hasConfirm: true,
                    onClick: (data, index) => {
                        this.deleteItem(index)
                    }
                })
            }
            return actions
        }
    }
    onSearchWithParent(id?: number) {
        throw new Error('未设置查询函数')
    }
    onShowEdit(id?: number) {
        console.log(id)
        throw new Error('未设置修改函数')
    }
    onAddChild(id?: number) {
        console.log(id)
        throw new Error('未设置新增函数')
    }
    add(id?: number) {
        console.log(id)
        throw new Error('未设置新增函数')
    }
    async changeState(value: boolean, id: number) {
        await this.request('/menu/update', { data: { id, isShow: value } })
    }
    async setIcon() {
        const lable = this.labels.icon as interCustomizeTable<Partial<interfaceMenu>, 'icon'>
        if (!lable) return
        const icons: any = await import('@element-plus/icons-vue')
        lable.formatter = ({ value }) => value && icons[value] ? h(ElIcon, {}, { default: () => h(icons[value]) }) : ''
    }
    init() {
        this.setIcon()
    }
}
export class MenuForm extends Form<interfaceMenu> {
    showIcon: boolean
    constructor() {
        super()
        this.baseUrl = "/menu"
        this.label_width = "8em"
        this.title = "修改菜单"
        this.data.type = MENUTYPE.目录
        this.data.isShow = true
        this.showIcon = false
        this.upload = ['img']
    }
    async setLabels(icons: any, labels: any) {
        const vLabel: RuleItem[] = [{ type: 'string', required: true, message: '请输入身份名称' },
        { type: 'string', validator: (rule, value) => value ? value.length < 12 : false, message: '菜单名称最多12位' }]
        this.rule = {
            name: vLabel
        }
        this.setItem({
            type: {
                prop: "type",
                label: "类型",
                type: 'radio',
                inpDefault: () => MENUTYPE.目录,
                options: [{ value: MENUTYPE.目录, label: '目录' }, { value: MENUTYPE.菜单, label: '菜单' }, { value: MENUTYPE.按钮, label: '按钮' }],
                rule: Form.getVantRule(vLabel)
            },
            name: {
                prop: "name",
                type: 'text',
                label: "菜单名称",
                rule: Form.getVantRule(vLabel)
            },
            viewPath: {
                prop: "viewPath",
                label: "视图地址",
                type: 'text',
                show: ({ data }) => data.type === MENUTYPE.菜单
            },
            parentId: {
                prop: "parent.id",
                label: "上级菜单",
                type: 'cascader',
                placeholder: "上级菜单",
                checkStrictly: true,
                clearable: true,
                options: labels,
                props: {
                    label: 'name',
                    value: 'id',
                    children: 'childMenus',
                },
                link: true,
            },
            router: {
                prop: "router",
                label: "路由地址",
                type: 'text',
                inpDefault: () => '/'
            },
            orderNum: {
                prop: "orderNum",
                label: "排序",
                type: 'number',
                placeholder: "排序",
                default: '0',
                max: 100,
                rule: Form.getVantRule([{ type: 'number', required: true, message: '请输入排序' }])
            },
            perms: {
                prop: "perms",
                label: "权限标识",
                type: 'text',
                placeholder: "权限标识"
            },
            isShow: {
                prop: "isShow",
                label: "是否显示",
                type: 'bool',
                inpDefault: () => true
            },
            img: {
                prop: 'img',
                label: '移动端图标',
                type: 'image'
            },
            icon: {
                prop: 'icon', label: '图标', type: 'customize', vform: ({ value }) => h('div', {}, [h(ElButton, {
                    onClick: () => {
                        this.showIcon = true
                    }
                }, {
                    default: () => value ? h(ElIcon, {}, { default: () => h(icons[value as keyof typeof icons]) }) : '无'
                })])
            }
        }, this.labels)
    }
    async setMenus() {
        return await this.request('/menu/select', { method: 'GET', cache: 'global' })
    }
    async setIcon() {
        return await import('@element-plus/icons-vue')
    }
    async init() {
        const icons = await this.setIcon()
        const menus = await this.setMenus()
        this.setLabels(icons, menus)
    }
    showCroppe(url: string) {
        console.log(url)
        throw new Error('未设置显示编辑图片的方法')
    }
}